package gui.product;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Calendar;
import java.util.GregorianCalendar;

import javax.swing.Timer;

import gui.common.*;
import core.Amount;
import core.Barcode;
import core.CoreFacade;
import core.Product;
import core.Unit;

/**
 * Controller class for the add item view.
 */
public class AddProductController extends Controller implements
		IAddProductController {
	
	private CoreFacade core;
	private String productBarcode;
	private boolean canAdd, validAmount, validInts;
	private boolean validDescription, countBox;
	private String description;
	private String shelfLife;
	private String sizeValue;
	private String threeMonthSupply;
	private SizeUnits units;

	private Timer scannerTimer = new Timer(200,
			
			new ActionListener()
			{

				@Override
				public void actionPerformed(ActionEvent arg0) 
				{
					startAutoItentify();	
				}
		
			}
			
			);
	
	/**
	 * Constructor.
	 * 
	 * @param view Reference to the add product view
	 * @param barcode Barcode for the product being added
	 */
	public AddProductController(IView view, String barcode) {
		super(view);
		
		core = CoreFacade.getInstance();
		
		productBarcode = barcode;
		
		getView().enableBarcode(false);
		
		canAdd = false;
		
		getView().setSizeValue("1");
		
		getView().setShelfLife("0");
		
		getView().setSupply("0");
		
		construct();
	}

	//
	// Controller overrides
	//
	
	/**
	 * Returns a reference to the view for this controller.
	 * 
	 * {@pre None}
	 * 
	 * {@post Returns a reference to the view for this controller.}
	 */
	@Override
	protected IAddProductView getView() {
		return (IAddProductView)super.getView();
	}

	/**
	 * Sets the enable/disable state of all components in the controller's view.
	 * A component should be enabled only if the user is currently
	 * allowed to interact with that component.
	 * 
	 * {@pre None}
	 * 
	 * {@post The enable/disable state of all components in the controller's view
	 * have been set appropriately.}
	 */
	@Override
	protected void enableComponents() 
	{
		getView().enableOK(canAdd);
		getView().enableSizeValue(countBox);
		// The methods below will all deal with the autosearch i think...
		//getView().enableBarcode(value); this will have to do with barcode scanning?
		//getView().enableDescription(value); this will deal with auto search
		//getView().enableShelfLife();
		//getView().enableSizeUnit(value);
		//getView().enableSupply(value);
		if (scannerTimer == null) return;
		getView().setDescription("Identifying Product - Please Wait ");
		getView().enableBarcode(false);
		getView().enableDescription(false);
		getView().enableOK(false);
		getView().enableShelfLife(false);
		getView().enableSizeUnit(false);
		getView().enableSizeValue(false);
		getView().enableSupply(false);
	}
	
	/**
	 * Used to enable/disable components with the associated view
	 * 
	 * @param enable true indicates the Add button should be enabled, 
	 * 				 false indicates disabled
	 */
	public void enableDisableComponents(boolean enable)
	{
		
	}

	/**
	 * Loads data into the controller's view.
	 * 
	 *  {@pre None}
	 *  
	 *  {@post The controller has loaded data into its view}
	 */
	@Override
	protected void loadValues() 
	{
		getView().setBarcode(productBarcode);
		
		if (scannerTimer != null) scannerTimer.start();
	}

	/**
	 * This is called to query the view's components to get the
	 * appropriate data
	 */
	public void getValues()
	{
		description = getView().getDescription(); // string
		shelfLife = getView().getShelfLife(); // string
		units = getView().getSizeUnit(); // sizeUnits
		sizeValue = getView().getSizeValue(); // string
		threeMonthSupply = getView().getSupply(); // string
	}
	
	//
	// IAddProductController overrides
	//
	
	/**
	 * This method is called when any of the fields in the
	 * add product view is changed by the user.
	 */
	@Override
	public void valuesChanged() 
	{
		getValues();
		
		if(units == SizeUnits.Count)
		{
			sizeValue = "1";
			getView().setSizeValue(sizeValue);
		}
		
		float f;
		try{
			f = Float.parseFloat(sizeValue);
		} catch (Exception e){
			f = -1;
		}
		Amount amt = new Amount(units.toUnit(),f);
		int shelf_life;
		try{
			shelf_life = Integer.parseInt(shelfLife);
		}catch (Exception e)
		{
			shelf_life = -1;
		}
		
		int three_month_supply;
		try{
			three_month_supply = Integer.parseInt(threeMonthSupply);
		}catch (Exception e)
		{
			three_month_supply = -1;
		}

		//count box will be disables IFF unit type is count
		countBox = (amt.getUnit() != Unit.count);
		//check amount is valid
		validAmount = amt.isValidAmount();
		//check the others are non negative
		validInts = (shelf_life > -1) && (three_month_supply > -1);
		// check description is non empty
		validDescription = !description.isEmpty();
		// all of the above must be true for the ok button to be up.
		canAdd = validAmount && validInts && validDescription;
		enableComponents();
	}
	
	/**
	 * This method is called when the user clicks the "OK"
	 * button in the add product view.
	 */
	@Override
	public void addProduct() 
	{
		Calendar newDate = new GregorianCalendar();
		Barcode bCode = new Barcode(productBarcode);
		Amount amt = new Amount(units.toUnit(),Float.parseFloat(sizeValue));
		int shelf_life = Integer.parseInt(shelfLife);
		int three_month_supply = Integer.parseInt(threeMonthSupply);

		Product newProduct = new Product(newDate, bCode, description, amt,
				 shelf_life, three_month_supply);
		
		// where do i get pc
		try {
			//core.addProduct(newProduct, null);
			core.addProduct(newProduct);
		} 
		catch (Exception e) 
		{
			//What do to here?
			getView().displayErrorMessage("Error Adding Product in AddProductController");
		}
	}
	
	public void startAutoItentify()
	{
		
		
		//destroy the autoidentify timer
		if (scannerTimer != null) scannerTimer.stop();
		scannerTimer = null;
		
		//get a descriptions for it.
		String prodDescription = core.idProduct(productBarcode);
		
		if (prodDescription != null)
		{
			getView().setDescription(prodDescription);
			//getView().enableOK(true);
		}
		else
		{
			getView().setDescription("");
		}
		
		getView().enableDescription(true);
		getView().enableShelfLife(true);
		getView().enableSizeUnit(true);
		getView().enableSizeValue(true);
		getView().enableSupply(true);
		
		valuesChanged();
	}

}

